package measurement.packetsPatterns;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.Vector;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.Priority;
import org.apache.log4j.PropertyConfigurator;

import measurement.main.WiimoteMeasurementListener;

import wiiusej.Wiimote;
import wiiusej.apptest.statistics.AccelerationPaquet;
import wiiusej.apptest.statistics.PacketController;
import wiiusej.apptest.statistics.PacketManager;
import wiiusej.apptest.statistics.PacketWraped;
import wiiusej.motionAlgorithms.Centroid;
import wiiusej.motionAlgorithms.CentroidsEnum;
import wiiusej.motionAlgorithms.Kmeans;
import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent;
import wiiusej.wiiusejevents.utils.WiimoteBasicListener;


public class WiimotePacketListener extends WiimoteMeasurementListener{

	//Logger
	private static Logger fileLogger;
	private static Logger resultLogger;
	
	private int packetSize = 0, oldPacketSize = 0;
	
	//kmeans algorithm centroids
	private CentroidsEnum centroidsType;
	private Vector<Centroid> centroids = new Vector<Centroid>();
	
	//PacketController
	private PacketController pController;
	protected long randomID;
	
	
			
	public WiimotePacketListener(ExecutorService exe, Wiimote aux,
			String measurementLength) {
		
		super(exe, aux, measurementLength);
		
		PropertyConfigurator.configure("log4j.properties");
		fileLogger = Logger.getLogger("packetStats");		
		resultLogger = Logger.getLogger("packetStatsResults");
		
		//Superclass methods
		//register this listener in the Wiimote's listener list
		registerListeners();
		//activate the sense of motion, needed to receive the motion packets from associated Wiimote
		activateMotionSensing();		
		fileLogger.info("Mesurement Received: " + this.measurementLength);
		
		//init centroids datastructure
		initCentroids();
		
	}	
	
	
	@Override
	public void registerListeners(){
		wiimote.addWiiMoteEventListeners(this);		
	}
	
	@Override
	public void onMotionSensingEvent(MotionSensingEvent e, long packetRefNumber) {
		
		packetSize = myPackets.getMyEventVector().getPackets().size();
		
		if(packetSize >= measurementLength){
			removeListener();
			measurementReport();			
		}else{
			
			getPacketStatistics(e);			
			
			if(packetSize>oldPacketSize){
				//sendToKmeans();
				oldPacketSize++;
			}			
		}
		
		
		
	}
	
	
	private void getPacketStatistics(MotionSensingEvent e){
		//WARNING: ADD FROMSYSTEM QUEUE TO CALL PACKAGE MANAGER!!
		Future future = 
			exe.submit(new PacketManager(e, wiimote.getId(), randomID, myPackets, null, null));
				
		try {
			myPackets = (PacketWraped) future.get();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		} catch (ExecutionException e1) {
			e1.printStackTrace();
		}			
		
		
		
	}
	
	private void initCentroids() {		
		Centroid slowCentroid = new Centroid(centroidsType.SLOW);
		Centroid bigCentroid = new Centroid(centroidsType.BIG);
		Centroid roboticCentroid = new Centroid(centroidsType.ROBOTIC);
		
		centroids.add(slowCentroid);
		centroids.add(bigCentroid);
		centroids.add(roboticCentroid);
		
		fileLogger.debug("");
		fileLogger.debug("Adding Centroids:");
		for(Centroid c : centroids){
			fileLogger.debug(c.toString());			
		}
		
	}
	
	/*
	private void sendToKmeans(){		
		Future kmeans = exe.submit(new Kmeans(myPackets.getMyEventVector().getPackets(), centroids));	
						
		try {
			Boolean result = (Boolean) kmeans.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}*/
	
	
	private void measurementReport(){
		
		fileLogger.info("");		
		fileLogger.info("*************************************************");
		fileLogger.info("PACKET MEASUREMENT HAS FINISHED!! " + 
				"#PERIODS: " + myPackets.getMyEventVector().getPackets().size());
		fileLogger.info("*************************************************");
		
		fileLogger.info("");
		fileLogger.info("MyEventsVector: ");
		
		double average = 0;		
		
		for(AccelerationPaquet i : myPackets.getMyEventVector().getPackets()){
			average += i.getCounter();			
			fileLogger.info(i.printTimeStamp());		
			resultLogger.info(i.getCounter());
		}		
		fileLogger.info("");
		fileLogger.info("Packet Average: " + (average/myPackets.getMyEventVector().getPackets().size()));
		resultLogger.info("");
		resultLogger.info("Average: " + (average/myPackets.getMyEventVector().getPackets().size()));
		
	}
	
	

}
